import { Controller, Get, Post, Body, Patch, Param, Delete, Query, ParseUUIDPipe, UseInterceptors, ClassSerializerInterceptor, HttpStatus, HttpCode, BadRequestException, NotFoundException, InternalServerErrorException } from '@nestjs/common';
import { DiscussionPostService } from './discussion-post.service';
import { CreateDiscussionPostDto } from './dto/create-discussion-post.dto';
import { UpdateDiscussionPostDto } from './dto/update-discussion-post.dto';
import { DiscussionPost } from './entities/discussion-post.entity';
import { PostResponseDto } from './dto/post-response.dto';

@Controller('discussion-posts')
@UseInterceptors(ClassSerializerInterceptor)
export class DiscussionPostController {
  constructor(private readonly discussionPostService: DiscussionPostService) {}

  @Post()
  @HttpCode(HttpStatus.CREATED)
  async create(@Body() createDiscussionPostDto: CreateDiscussionPostDto): Promise<PostResponseDto> {
    try {
      // Validate author ID format first
      if (!createDiscussionPostDto.authorId || !this.isValidUUID(createDiscussionPostDto.authorId)) {
        throw new BadRequestException(`Invalid authorId format: ${createDiscussionPostDto.authorId}`);
      }
      
      return await this.discussionPostService.create(createDiscussionPostDto);
    } catch (error) {
      console.error('Controller error creating discussion post:', error);
      
      if (error instanceof BadRequestException || error instanceof NotFoundException) {
        throw error; // Re-throw validation errors
      }
      
      throw new InternalServerErrorException('Failed to create discussion post');
    }
  }

  // Helper method to validate UUID format
  private isValidUUID(uuid: string): boolean {
    if (!uuid) return false;
    
    // Use a more relaxed pattern that matches UUIDv4 and UUIDv7
    // This should help with uuidv7 format which might be slightly different
    const regex = /^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$/i;
    
    // If the format matches, return true
    if (regex.test(uuid)) {
      return true;
    }
    
    // Log for debugging
    console.log(`UUID validation failed for: ${uuid}`);
    return false;
  }

  @Get()
  findAll(@Query('visible') visible?: string, @Query('category') category?: string): Promise<PostResponseDto[]> {
    if (visible === 'true') {
      return this.discussionPostService.findAllVisible();
    }
    return this.discussionPostService.findAll();
  }

  @Get(':id')
  async findOne(@Param('id', ParseUUIDPipe) id: string): Promise<PostResponseDto> {
    console.log(`Request received for post with ID: ${id}`);
    try {
      const result = await this.discussionPostService.findOneFormatted(id);
      console.log(`Successfully found post with ID: ${id}`);
      return result;
    } catch (error) {
      console.error(`Error finding post with ID ${id}:`, error.message);
      throw error;
    }
  }

  @Patch(':id')
  update(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() updateDiscussionPostDto: UpdateDiscussionPostDto,
  ): Promise<PostResponseDto> {
    return this.discussionPostService.update(id, updateDiscussionPostDto);
  }

  @Delete(':id')
  @HttpCode(HttpStatus.NO_CONTENT)
  remove(@Param('id', ParseUUIDPipe) id: string): Promise<void> {
    return this.discussionPostService.remove(id);
  }

  @Post(':id/like')
  @HttpCode(HttpStatus.OK)
  async likePost(@Param('id', ParseUUIDPipe) id: string): Promise<PostResponseDto> {
    try {
      const post = await this.discussionPostService.likePost(id);
      return PostResponseDto.fromEntity(post);
    } catch (error) {
      console.error(`Error liking post ${id}:`, error);
      
      if (error instanceof NotFoundException) {
        throw error;
      }
      
      throw new InternalServerErrorException('Failed to like post');
    }
  }

  @Get('by-author/:authorId')
  async findByAuthorId(@Param('authorId', ParseUUIDPipe) authorId: string): Promise<PostResponseDto[]> {
    try {
      return await this.discussionPostService.findByAuthorId(authorId);
    } catch (error) {
      console.error(`Error fetching posts for author ${authorId}:`, error);
      throw new InternalServerErrorException('Failed to fetch user posts');
    }
  }
} 